package com.jzsec.sharding.strategy;

import com.google.common.collect.Range;
import com.jzsec.sharding.strategy.utils.DateFmtUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingValue;
import org.apache.shardingsphere.api.sharding.standard.RangeShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.RangeShardingValue;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

@Slf4j
public class Yyyy_mmTableShardingAlgorithm implements PreciseShardingAlgorithm<Integer>, RangeShardingAlgorithm<Integer> {

    public static void main(String[] args) throws Exception {
        System.out.println(DateFmtUtils.getYyyy_MM(20190901));
        System.out.println(new Yyyy_mmTableShardingAlgorithm().actualDataNodes("t_logasset", null, null));
        System.out.println(new Yyyy_mmTableShardingAlgorithm().actualDataNodes("t_logasset", 20190121, 20190209));
    }

    public Collection<String> doSharding(Collection<String> availableTargetNames, RangeShardingValue<Integer> shardingValue) {
        Range<Integer> valueRange = shardingValue.getValueRange();
        Collection<String> result = actualDataNodes(shardingValue.getLogicTableName(), valueRange.lowerEndpoint(), valueRange.upperEndpoint());
        log.info("{}, {}", shardingValue, result);
        return result;
    }

    public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<Integer> shardingValue) {
        String result = shardingValue.getLogicTableName() + DateFmtUtils.getYyyy_MM(shardingValue.getValue());
        log.info("{}, {}", shardingValue, result);
        return result;
    }

    public List<String> actualDataNodes(String logicTable, Integer beginYyyymmdd, Integer endYyyymmdd) {
        List<String> list = new ArrayList<String>();
        if (beginYyyymmdd == null) beginYyyymmdd = endYyyymmdd;
        if (endYyyymmdd == null) endYyyymmdd = beginYyyymmdd;
        if (beginYyyymmdd == null && endYyyymmdd == null) {
            beginYyyymmdd = endYyyymmdd = DateFmtUtils.getNow();
        }
        LocalDate startDate = DateFmtUtils.int2Date(beginYyyymmdd);
        LocalDate endDate = DateFmtUtils.int2Date(endYyyymmdd);
        startDate = startDate.withDayOfMonth(1);
        LocalDate index = startDate;
        while (index.compareTo(endDate) <= 0) {
            list.add(logicTable + DateFmtUtils._yyyy_MM.format(index));
            index = index.plusMonths(1);
        }
        return list;
    }

}
